package org.whuims.pois.common;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @VERSION 2013-12-27
 * Created by 声伟 on 13-12-27.
 */
public class TimeUtils {


    public static Date str2Date(String str, DateFormat f) {
        if (f == null) {
            return null;
        }
        try {
            return f.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static String date2Str(Date date, DateFormat f) {
        if (f == null) {
            return null;
        }
        String str = f.format(date);
        return str;
    }

    public static String calendar2Str(Calendar c, DateFormat f) {
        Date date = c.getTime();
        return date2Str(date, f);
    }

    public static Calendar str2Calendar(String str, DateFormat f) {
        try {
            Date date = f.parse(str);
            return date2Calendar(date);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static Calendar date2Calendar(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c;
    }

    public static Date calendar2Date(Calendar calendar) {
        return calendar.getTime();
    }

    /**
     * 得到一个从startDate开始，增加nDay天（为负数则向前推）的天数。
     * 如果该日期在endDate之后或者在startDate之前，则返回null
     * 日期格式：yyyy-MM-dd
     *
     * @param nDay
     * @param startDate
     * @param endDate
     * @return
     */
    public static String getDay(String startDate, String currentDate, int nDay, String endDate) {
        SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");
        if (currentDate == null) {  //设置默认当前日期
            currentDate = TimeUtils.date2Str(new Date(), f); //当前日期
        }

        Calendar cc = Calendar.getInstance();
        cc.setTime(str2Date(currentDate, f));
        cc.add(Calendar.DAY_OF_MONTH, nDay);
        //起始日期限制
        if (startDate != null) {
            Calendar cs = Calendar.getInstance();
            cs.setTime(str2Date(startDate, f));
            if (cs != null && cc.before(cs)) {
                return null;
            }
        }
        //结束日期限制
        if (endDate != null) {
            Calendar ce = Calendar.getInstance();
            ce.setTime(str2Date(endDate, f));
            if (ce != null && cc.after(ce)) {
                return null;
            }
        }
        return calendar2Str(cc, f);
    }

    public static int dValue(String startDate, String endDate) {
        Calendar start = toDayCal(startDate);
        Calendar end = toDayCal(endDate);
        return dValue(start, end);
    }

    public static int dValue(Calendar start, Calendar end) {
        if (start == null || end == null) return -1;
        long dif = end.getTimeInMillis() - start.getTimeInMillis();
        return new Long(dif / (1000 * 60 * 60 * 24)).intValue();
    }

    /**
     * 将一个时间字符串精确到日返回Calendar
     *
     * @param dateStr
     * @return
     */
    public static Calendar toDayCal(String dateStr) {
        if (dateStr == null || dateStr.trim().length() <= 9) {
            return null;
        }
        dateStr = dateStr.substring(0, 10);
        return str2Calendar(dateStr, new SimpleDateFormat("yyyy-MM-dd"));
    }

    public static void main(String[] args) {
        System.out.println(getDay("2013-11-11", "2013-11-11", 0, null));
        System.out.println(getNow());
        System.out.println(dValue("2012-11-11 23:22:45", "2013-12-0"));
        System.out.println(getTimestamp("2012-11-11", false));
        System.out.println(getTimestamp("2012-11-11", true));

    }

    public static String getNow() {
        return getDay(null, null, 0, null);
    }

    /**
     * 从min到max，按照groupGrain增加各个时间段并返回时间标识
     *
     * @param min
     * @param max
     * @param groupGrain
     * @return
     */
    public static List<String> iterateTimeList(Calendar min, Calendar max, int groupGrain) {
        //这里不能改min的值，因为min是从其他地方引用过来的，会修改那边的值
        List<String> result = new ArrayList<String>();
        String timeStr = "";
        Calendar current = Calendar.getInstance();
        current.setTime(min.getTime());
        while (current.before(max)) {
            result.add(getTimeLabel(groupGrain, current));
            current.add(getFieldValue(groupGrain), 1);
        }
        if (getTimeLabel(groupGrain, current).equals(getTimeLabel(groupGrain, max))) {
            result.add(getTimeLabel(groupGrain, min));
        }
        return result;
    }

    public static int getFieldValue(int groupGrain) {
        if (groupGrain == 0) {
            return Calendar.DAY_OF_MONTH;
        } else if (groupGrain == 1) {
            return Calendar.MONTH;
        } else {
            return Calendar.YEAR;
        }
    }

    public static String getTimeLabel(int groupGrain, Calendar tc) {
        int year = tc.get(Calendar.YEAR);
        int month = tc.get(Calendar.MONTH) + 1;
        int day = tc.get(Calendar.DAY_OF_MONTH);
        String label;
        String monthLabel = month < 10 ? "0" + month : month + "";
        if (groupGrain == 0) {
            String dayLabel = day < 10 ? "0" + day : "" + day;
            label = year + "-" + monthLabel + "-" + dayLabel;

        } else if (groupGrain == 1) {
            label = year + "-" + monthLabel;
        } else {
            label = year + "";
        }
        return label;
    }

    public static Timestamp getTimestamp(String startDate, boolean start) {
        if (startDate == null) {
            return null;
        }
        Calendar c = str2Calendar(startDate, new SimpleDateFormat("yyyy-MM-dd"));
        if (start) {
            c.set(Calendar.HOUR_OF_DAY, 0);
            c.set(Calendar.MINUTE, 0);
            c.set(Calendar.SECOND, 0);
        } else {
            c.set(Calendar.HOUR_OF_DAY, 23);
            c.set(Calendar.MINUTE, 59);
            c.set(Calendar.SECOND, 59);
        }
        return new Timestamp(c.getTime().getTime());
    }

}
